﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ServiceModel;
using Client.TaskService;
using TaskManagement.ModelLayer;
using System.Text.RegularExpressions;

namespace Client
{
    public partial class TaskManagementForm : Form
    {
        private BindingSource _bsTask;
        private BindingSource _bsWorkflow;
        private Regex _numbersOnlyRegex;

        public TaskManagementForm()
        {
            InitializeComponent();
            _numbersOnlyRegex = new Regex(@"(\d|[\b])+");

            _bsTask = new BindingSource();
            _bsTask.AllowNew = false;
            _bsTask.CurrentChanged += new EventHandler(_bs_CurrentChanged);
            dataGridViewTask.DataSource = _bsTask;

            _bsWorkflow = new BindingSource();
            _bsWorkflow.AllowNew = false;
            _bsWorkflow.CurrentChanged += new EventHandler(_bsWorkflow_CurrentChanged);
            dataGridViewWorkflow.DataSource = _bsWorkflow;
        }



        # region Task
        private void taskTab_Enter(object sender, EventArgs e)
        {
            try
            {
                using (TaskServiceClient service = new TaskServiceClient("nettcp"))
                {

                    if (comboBoxTaskAccount.Items.Count == 0)
                    {
                        List<string> list = service.GetAccounts();
                        if(list != null)
                            comboBoxTaskAccount.Items.AddRange(list.ToArray());
                    }

                    if (comboBoxTaskDelivery.Items.Count == 0)
                    {
                        List<string> list = service.GetDeliverys();
                        if (list != null)
                            comboBoxTaskDelivery.Items.AddRange(list.ToArray());
                    }

                    if (comboBoxTaskTag.Items.Count == 0)
                    {
                        List<string> list = service.GetTags();
                        if (list != null)
                            comboBoxTaskTag.Items.AddRange(list.ToArray());
                    }


                    if (_bsTask.DataSource == null)
                    {
                        Task t = new Task();
                        _bsTask.DataSource = service.SearchTasks(t);
                    }

                    if (_bsTask.Current != null)
                    {
                        Task t= (Task)_bsTask.Current;
                        UpdateTaskControls(t);
                    }


                }

            }
            catch (CommunicationException)
            {
                MessageBox.Show(this, "An error occured while communicating with the server and the request could not be processed", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (TimeoutException)
            {
                MessageBox.Show(this, "The request timedout", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        /// <summary>
        /// Displayes data from the datagridview in the controls above
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void _bs_CurrentChanged(object sender, EventArgs e)
        {
            BindingSource bs = (BindingSource)sender;
            Task t = (Task)bs.Current;
            if (t != null)
                UpdateTaskControls(t);
        }

        private void UpdateTaskControls(Task t)
        {
            textBoxTaskId.Text = t.Id.ToString();
            comboBoxTaskAccount.SelectedItem = t.Account;
            comboBoxTaskTag.SelectedItem = t.Tag;
            comboBoxTaskDelivery.SelectedItem = t.Delivery;
            textBoxTaskDescription.Text = t.Description;
            textBoxAssignedTo.Text = t.AssignedTo;
            dateTimePickerTask.Value = (DateTime)t.Date;
            comboBoxTaskStatus.SelectedItem = t.Status;
            textBoxTaskEstimate.Text = t.Estiamte.ToString();
            textBoxTaskTimeSpent.Text = t.TimeSpent.ToString();
        }

        private void buttonCreateTask_Click(object sender, EventArgs e)
        {
            try
            {
                using (TaskServiceClient service = new TaskServiceClient("nettcp"))
                {
                    Task t = CreateTaskFromControls();
                    t.Id = 0;

                    int result = service.CreateTask(t);
                    if (result > 0)
                    {
                        t.Id = result;
                        _bsTask.Add(t);
                        _bsTask.MoveLast();
                        dateTimePickerTask.Checked = true;
                        UpdateComboboxes(t.Account, t.Tag, t.Delivery);
                    }
                    else
                    {
                        MessageBox.Show(this, "Could not create task", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }

                }

            }
            catch (CommunicationException)
            {
                MessageBox.Show(this, "An error occured while communicating with the server and the request could not be processed", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (TimeoutException)
            {
                MessageBox.Show(this, "The request timedout", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void buttonDeleteTask_Click(object sender, EventArgs e)
        {
            if (dataGridViewTask.SelectedRows.Count == 0)
            {
                MessageBox.Show(this, "Cannot delete while no items are selected", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {

                DialogResult dr = MessageBox.Show(this, "Are you sure you want to delete the seleted task(s)?"
                    , "Delete", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (dr == DialogResult.OK)
                {
                    try
                    {

                        int result = 0;
                        List<Task> tasksToDelete = new List<Task>();
                        using (TaskServiceClient service = new TaskServiceClient("nettcp"))
                        {
                            foreach (DataGridViewRow row in dataGridViewTask.SelectedRows)
                            {
                                Task t = (Task)row.DataBoundItem;
                                tasksToDelete.Add(t);
                            }

                            result = service.DeleteTasks(tasksToDelete);
                        }
                        if (result != 0)
                        {
                            foreach (Task t in tasksToDelete)
                            {
                                _bsTask.Remove(t);
                            }

                            if (_bsTask.Count != 0)
                            {
                                dataGridViewTask.Rows[_bsTask.Position].Selected = true;
                            }

                        }
                        else
                        {
                            MessageBox.Show(this, "Unable to delete task(s)", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }

                    }
                    catch (CommunicationException)
                    {
                        MessageBox.Show(this, "An error occured while communicating with the server and the request could not be processed", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (TimeoutException)
                    {
                        MessageBox.Show(this, "The request timedout", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }

        }


        private void buttonUpdateTask_Click(object sender, EventArgs e)
        {
            try
            {

            if (dataGridViewTask.SelectedRows.Count > 1)
            {
                MessageBox.Show(this, "Cannot update while more than one item is selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {

                Task current = (Task)_bsTask.Current;
                if (current != null)
                {
                        Task task = CreateTaskFromControls();
                        task.Id = current.Id;
                        int result = 0;
                        using (TaskServiceClient service = new TaskServiceClient("nettcp"))
                        {
                            task.Id = current.Id;
                            result = service.UpdateTask(task);
                        }

                        if (result != 0)
                        {
                            current.Account = task.Account;
                            current.Date = task.Date;
                            current.Delivery = task.Delivery;
                            current.Description = task.Description;
                            current.Estiamte = task.Estiamte;
                            current.Status = task.Status;
                            current.Tag = task.Tag;
                            current.TimeSpent = task.TimeSpent;
                            _bsTask.ResetCurrentItem();
                            UpdateComboboxes(current.Account, current.Tag, current.Delivery);
                        }
                        else
                        {
                            MessageBox.Show(this, "Could not update task", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }

                }
                else
                {
                    MessageBox.Show(this, "Cannot update because no item is selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
            }

            }
            catch (CommunicationException)
            {
                MessageBox.Show(this, "An error occured while communicating with the server and the request could not be processed", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (TimeoutException)
            {
                MessageBox.Show(this, "The request timedout", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        /// <summary>
        /// Creates a task from the data in the controls
        /// </summary>
        /// <returns>The new task object</returns>
        private Task CreateTaskFromControls()
        {
            Task t = new Task();
            if (!string.IsNullOrEmpty(textBoxTaskId.Text))
                t.Id = int.Parse(textBoxTaskId.Text);

            t.Account = comboBoxTaskAccount.Text;
            t.Date = dateTimePickerTask.Value;
            t.Delivery = comboBoxTaskDelivery.Text;
            t.Description = textBoxTaskDescription.Text;
            if (comboBoxTaskStatus.SelectedItem != null)
            {
                t.Status = comboBoxTaskStatus.SelectedItem.ToString();
            }
            else
            {
                t.Status = "Pending";
            }

            t.Tag = comboBoxTaskTag.Text;

            if (!string.IsNullOrEmpty(textBoxTaskEstimate.Text))
                t.Estiamte = int.Parse(textBoxTaskEstimate.Text);
            else
                t.Estiamte = 0;

            if (!string.IsNullOrEmpty(textBoxTaskTimeSpent.Text))
                t.TimeSpent = int.Parse(textBoxTaskTimeSpent.Text);
            else
                t.TimeSpent = 0;

            return t;
        }



        private void textBoxNumbersOnly_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!_numbersOnlyRegex.IsMatch(e.KeyChar.ToString()))
                e.Handled = true;
        }

        private void buttonClearTasksControls_Click(object sender, EventArgs e)
        {
            textBoxTaskId.Clear();

            comboBoxTaskAccount.Text = null;
            comboBoxTaskAccount.SelectedItem = null;

            comboBoxTaskDelivery.Text = null;
            comboBoxTaskDelivery.SelectedItem = null;

            comboBoxTaskTag.Text = null;
            comboBoxTaskTag.SelectedItem = null;

            textBoxTaskDescription.Clear();
            textBoxTaskEstimate.Clear();
            textBoxTaskTimeSpent.Clear();
            textBoxAssignedTo.Clear();
            comboBoxTaskStatus.SelectedItem = null;
            dateTimePickerTask.Value = DateTime.Today;
            dateTimePickerTask.Checked = false;

        }

        /// <summary>
        /// Creates the search based on the input in the controls above the datagridview
        /// Sends the search request to the server and sets the reply as the current items of the binding source
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonTaskSearch_Click(object sender, EventArgs e)
        {
            try
            {
            Task t = new Task();

            if (!string.IsNullOrWhiteSpace(comboBoxTaskAccount.Text))
                t.Account = comboBoxTaskAccount.SelectedText;

            if (!string.IsNullOrWhiteSpace(comboBoxTaskDelivery.Text))
                t.Delivery = comboBoxTaskDelivery.Text;

            if (!string.IsNullOrEmpty(textBoxTaskDescription.Text))
                t.Description = textBoxTaskDescription.Text;

            if (!string.IsNullOrEmpty(textBoxTaskEstimate.Text))
                t.Estiamte = int.Parse(textBoxTaskEstimate.Text);

            if (!string.IsNullOrEmpty(textBoxTaskId.Text))
                t.Id = int.Parse(textBoxTaskId.Text);

            if (!string.IsNullOrEmpty(textBoxTaskTimeSpent.Text))
                t.TimeSpent = int.Parse(textBoxTaskTimeSpent.Text);

            if (!string.IsNullOrWhiteSpace(comboBoxTaskTag.Text))
                t.Tag = comboBoxTaskTag.Text;

            if (!string.IsNullOrEmpty(comboBoxTaskStatus.Text))
                t.Status = comboBoxTaskStatus.SelectedValue.ToString();

            if (dateTimePickerTask.Checked)
                t.Date = dateTimePickerTask.Value;
            
                using (TaskServiceClient service = new TaskServiceClient("nettcp"))
                {
                    _bsTask.DataSource = service.SearchTasks(t);
                    dataGridViewTask.Focus();
                    _bsTask.MoveFirst();
                }

            }
            catch (CommunicationException)
            {
                MessageBox.Show(this, "An error occured while communicating with the server and the request could not be processed", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (TimeoutException)
            {
                MessageBox.Show(this, "The request timedout", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void dataGridViewTask_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                DataGridView.HitTestInfo hitinfo = dataGridViewTask.HitTest(e.X, e.Y);
                if (hitinfo.RowIndex >= 0)
                    MessageBox.Show("ITWORKZES");
            }
        }

        private void UpdateComboboxes(string account, string tag, string delivery)
        {
            if (!comboBoxTaskAccount.Items.Contains(account))
                comboBoxTaskAccount.Items.Add(account);
	        
            if (!comboBoxTaskDelivery.Items.Contains(delivery))
                comboBoxTaskDelivery.Items.Add(delivery);

            if (!comboBoxTaskTag.Items.Contains(tag))
                comboBoxTaskTag.Items.Add(tag);
        }

        # endregion



        private void workflowTab_Enter(object sender, EventArgs e)
        {
            try
            {
                if (_bsWorkflow.DataSource == null)
                {
                    Workflow w = new Workflow();
                    using (TaskServiceClient service = new TaskServiceClient("nettcp"))
                    {
                        _bsWorkflow.DataSource = service.SearchWorkflow(w);
                    }
                
                }

                if (_bsWorkflow.Current != null)
                {
                    Workflow w = (Workflow)_bsWorkflow.Current;
                    UpdateWorkflowControls(w);
                }
            }
            catch (CommunicationException)
            {
                MessageBox.Show(this, "An error occured while communicating with the server and the request could not be processed", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (TimeoutException)
            {
                MessageBox.Show(this, "The request timedout", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }


        }

        void _bsWorkflow_CurrentChanged(object sender, EventArgs e)
        {
            BindingSource bs = (BindingSource)sender;
            Workflow w = (Workflow)bs.Current;
            if (w != null)
                UpdateWorkflowControls(w);
        }

        private void UpdateWorkflowControls(Workflow w)
        {
            textBoxWorkflowId.Text = w.Id.ToString();
            textBoxWorkflowName.Text = w.Name;
            textBoxWorkflowDescription.Text = w.Description;
            dateTimePickerWorkflowStartDate.Value = (DateTime)w.StartDate;
            textBoxWorkflowNumberOfTasks.Text = w.NumberOfTasks.ToString();
            textBoxWorkflowCompletion.Text = w.CompletionPercentage;
        }

        private void dataGridViewWorkflow_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            Workflow w = (Workflow)_bsWorkflow.Current;
            if (w.Tasks.Count > 0)
            {
                _bsTask.DataSource = w.Tasks;
                tabControl1.SelectedTab = taskTab;
            }
            else
            {
                MessageBox.Show(this, "This workflow has no task assigned to it", "No tasks assigned", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }

        private void buttonWorkflowClear_Click(object sender, EventArgs e)
        {
            textBoxWorkflowId.Clear();
            textBoxWorkflowName.Clear();
            textBoxWorkflowCompletion.Clear();
            textBoxWorkflowDescription.Clear();
            textBoxWorkflowNumberOfTasks.Clear();
            dateTimePickerWorkflowStartDate.Value = DateTime.Today;
            dateTimePickerWorkflowStartDate.Checked = false;
        }

        private void buttonCreateWorkflow_Click(object sender, EventArgs e)
        {
            try
            {
                using (TaskServiceClient service = new TaskServiceClient("nettcp"))
                {
                    Workflow w = CreateWorkflowFromControls();
                    w.Id = 0;

                    int result = service.CreateWorkflow(w);
                    if (result > 0)
                    {
                        w.Id = result;
                        _bsWorkflow.Add(w);
                        _bsWorkflow.MoveLast();
                        dateTimePickerTask.Checked = true;
                    }
                    else
                    {
                        MessageBox.Show(this, "Could not create workflow", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }

            }
            catch (CommunicationException)
            {
                MessageBox.Show(this, "An error occured while communicating with the server and the request could not be processed", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (TimeoutException)
            {
                MessageBox.Show(this, "The request timedout", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private Workflow CreateWorkflowFromControls()
        {
            Workflow w = new Workflow();

            if (!string.IsNullOrWhiteSpace(textBoxWorkflowId.Text))
                w.Id = int.Parse(textBoxWorkflowId.Text);

            if (!string.IsNullOrWhiteSpace(textBoxWorkflowName.Text))
                w.Name = textBoxWorkflowName.Text;

            if (!string.IsNullOrWhiteSpace(textBoxWorkflowDescription.Text))
                w.Description = textBoxWorkflowDescription.Text;

            w.StartDate = dateTimePickerWorkflowStartDate.Value;

            return w;
        }

        private void buttonUpdateWorkflow_Click(object sender, EventArgs e)
        {
            try
            {
                if (dataGridViewWorkflow.SelectedRows.Count > 1)
                {
                    MessageBox.Show(this, "Cannot update while more than one item is selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    Workflow current = (Workflow)_bsWorkflow.Current;                
                    if (current != null)
                    {
                        Workflow workflow = CreateWorkflowFromControls();
                        workflow.Id = current.Id;
                        string result = "";
                        using (TaskServiceClient service = new TaskServiceClient("nettcp"))
                        {
                            result = service.UpdateWorkflow(workflow);
                        }

                        if (result.Equals("1"))
                        {
                            current.Name = workflow.Name;
                            current.StartDate = workflow.StartDate;
                            current.Description = workflow.Description;
                            _bsWorkflow.ResetCurrentItem();
                        }
                        else
                        {
                            switch (result)
                            {
                                case "0":
                                    MessageBox.Show(this, "Could not update workflow", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                    break;
                                default:
                                    MessageBox.Show(this, result, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                                    break;
                            }
                            
                        }

                    }
                    else
                    {
                        MessageBox.Show(this, "Cannot update because no item is selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    }
                }

            }
            catch (CommunicationException)
            {
                MessageBox.Show(this, "An error occured while communicating with the server and the request could not be processed", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            catch (TimeoutException)
            {
                MessageBox.Show(this, "The request timedout", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void buttonDeleteWorkflow_Click(object sender, EventArgs e)
        {
            if (dataGridViewWorkflow.SelectedRows.Count == 0)
            {
                MessageBox.Show(this, "Cannot delete while no items are selected", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            else
            {

                DialogResult dr = MessageBox.Show(this, "Are you sure you want to delete the seleted workflows(s)?\nDeleting this workflow will delete all tasks that are part of it"
                    , "Delete", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
                if (dr == DialogResult.OK)
                {
                    try
                    {

                        int result = 0;
                        List<Workflow> workflowsToDelete = new List<Workflow>();
                        using (TaskServiceClient service = new TaskServiceClient("nettcp"))
                        {
                            foreach (DataGridViewRow row in dataGridViewWorkflow.SelectedRows)
                            {
                                Workflow w = (Workflow)row.DataBoundItem;
                                workflowsToDelete.Add(w);
                            }

                            result = service.DeleteWorkflows(workflowsToDelete);
                        }
                        if (result == 1)
                        {
                            foreach (Workflow w in workflowsToDelete)
                            {
                                _bsWorkflow.Remove(w);
                            }

                            if (_bsWorkflow.Count != 0)
                            {
                                dataGridViewWorkflow.Rows[_bsWorkflow.Position].Selected = true;
                            }

                        }
                        else
                        {
                            MessageBox.Show(this, "Unable to delete workflows(s)", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        }

                    }
                    catch (CommunicationException)
                    {
                        MessageBox.Show(this, "An error occured while communicating with the server and the request could not be processed", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    catch (TimeoutException)
                    {
                        MessageBox.Show(this, "The request timedout", "Error while communication with server", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                }
            }
        }


    }
}
